"""
Case Type   : GUC参数测试
Case Name   : page_repair_function参数功能测试
Create At   : 2025/09/16
Owner       : jiangyan
Description :
    1、检查page_repair_function参数默认值
    2、修改参数值为on并验证
    3、修改参数值为off并验证
Expect      :
    1、参数默认值为off
    2、参数修改为on成功
    3、参数修改为off成功
History     :
"""

import unittest
import os
import time
from yat.test import macro
from yat.test import Node
from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

logger = Logger()
COMMONSH = CommonSH("PrimaryDbUser")

class GucTestCase(unittest.TestCase):
    def setUp(self):
        logger.info("==Opengauss_Function_Guc_Page_Repair_Case0001测试开始==")
        self.constant = Constant()
        # 检查数据库连接状态
        try:
            sql_cmd = "select 1;"
            result = COMMONSH.execut_db_sql(sql_cmd)
            logger.info(f"数据库连接测试: {result}")
            self.assertIn("1", result, "数据库连接失败")
        except Exception as e:
            self.fail(f"数据库连接异常: {e}")

    def verify_parameter_value(self, expected_value):
        """验证参数值是否正确"""
        sql_cmd = "show page_repair_function;"
        result = COMMONSH.execut_db_sql(sql_cmd)
        logger.info(f"参数查询结果: {result}")
    
        # 统一转换为小写便于处理
        result_lower = result.lower()
    
        # 先尝试简单匹配常见格式
        if f"page_repair_function | {expected_value}" in result_lower:
            logger.info(f"参数值验证成功: {expected_value}")
            return True
    
        # 解析参数值的简化逻辑
        actual_value = self._parse_parameter_value(result)
    
        if actual_value is None:
            self.fail(f"无法解析参数值，查询结果: {result}")
    
        logger.info(f"解析到的参数值: {actual_value}, 期望值: {expected_value}")
        self.assertEqual(actual_value, expected_value, 
                       f"参数值应为{expected_value}，但实际为{actual_value}")
        return True

    def _parse_parameter_value(self, result):
        """解析参数值的辅助函数"""
        lines = result.strip().split('\n')
    
        for line in lines:
            line = line.strip().lower()
        
            # 跳过无关行
            if not line or '----' in line or '(1 row)' in line:
                continue
        
            # 直接提取参数值
            value = self._extract_value_from_line(line)
            if value:
                return value
    
        # 如果上面没找到，尝试全局查找
        return self._find_value_in_result(result.lower())

    def _extract_value_from_line(self, line):
        """从单行文本中提取参数值"""
        # 格式: page_repair_function | off
        if 'page_repair_function' in line and '|' in line:
            parts = line.split('|')
            if len(parts) > 1:
                return parts[1].strip()
    
        # 格式: page_repair_function off
        if 'page_repair_function' in line:
            parts = line.split()
            if len(parts) > 1:
                return parts[1].strip()
    
        # 格式: off (单独一行)
        if line in ['on', 'off']:
            return line
    
        return None

    def _find_value_in_result(self, result_lower):
        """在整个结果中查找参数值"""
        if ' off' in result_lower and ' on' not in result_lower.replace('page_repair_function', ''):
            return 'off'
        elif ' on' in result_lower and ' off' not in result_lower.replace('page_repair_function', ''):
            return 'on'
        return None

    def test_guc_page_repair_function(self):
        # 步骤1：检查page_repair_function参数默认值
        logger.info("步骤1：检查page_repair_function参数默认值")
        self.verify_parameter_value("off")

        # 步骤2：设置page_repair_function为on
        logger.info("步骤2：设置page_repair_function为on")
        result = COMMONSH.execute_gsguc("set",
                                        self.constant.GSGUC_SUCCESS_MSG,
                                        "page_repair_function=on",
                                        node_name="all")
        self.assertTrue(result)

        # 步骤3：重启集群使参数生效
        logger.info("步骤3：重启集群使参数生效")
        COMMONSH.restart_db_cluster()
        time.sleep(10)  # 等待集群完全启动

        # 步骤4：检查参数是否设置成功，期望：on
        logger.info("步骤4：检查参数是否设置成功，期望：on")
        self.verify_parameter_value("on")

        # 步骤5：恢复参数默认值为off
        logger.info("步骤5：恢复参数默认值为off")
        result = COMMONSH.execute_gsguc("set",
                                        self.constant.GSGUC_SUCCESS_MSG,
                                        "page_repair_function=off",
                                        node_name="all")
        self.assertTrue(result)
        
        # 重启集群使参数生效
        COMMONSH.restart_db_cluster()
        time.sleep(10)

        # 步骤6：检查参数是否恢复成功，期望：off
        logger.info("步骤6：检查参数是否恢复成功，期望：off")
        self.verify_parameter_value("off")

        # 步骤7：使用reload方式设置参数为on
        logger.info("步骤7：使用reload方式设置参数为on")
        result = COMMONSH.execute_gsguc("reload",
                                        self.constant.GSGUC_SUCCESS_MSG,
                                        "page_repair_function=on",
                                        node_name="all")
        self.assertTrue(result)
        time.sleep(5)

        # 步骤8：检查reload方式设置结果，期望：on
        logger.info("步骤8：检查reload方式设置结果，期望：on")
        self.verify_parameter_value("on")

        # 步骤9：最终恢复参数默认值
        logger.info("步骤9：最终恢复参数默认值")
        result = COMMONSH.execute_gsguc("set",
                                        self.constant.GSGUC_SUCCESS_MSG,
                                        "page_repair_function=off",
                                        node_name="all")
        self.assertTrue(result)
        
        # 重启集群使参数生效
        COMMONSH.restart_db_cluster()
        time.sleep(10)

        # 验证最终参数值
        logger.info("验证最终参数值")
        self.verify_parameter_value("off")

    def tearDown(self):
        logger.info("恢复环境")
        # 确保参数恢复为默认值
        try:
            sql_cmd = "show page_repair_function;"
            result = COMMONSH.execut_db_sql(sql_cmd)
            if "off" not in result.lower() or "on" in result.lower():
                logger.info("参数未恢复为off，进行恢复操作")
                COMMONSH.execute_gsguc("set",
                                       self.constant.GSGUC_SUCCESS_MSG,
                                       "page_repair_function=off",
                                       node_name="all")
                time.sleep(3)
        except Exception as e:
            logger.warning(f"恢复参数时出错: {e}")
        
        logger.info("==Opengauss_Function_Guc_Page_Repair_Case0001测试结束==")